1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.primitives;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkElementIndex;
21 import static com.google.common.base.Preconditions.checkNotNull;
22 import static com.google.common.base.Preconditions.checkPositionIndexes;
23
24 import com.google.common.annotations.Beta;
25 import com.google.common.annotations.GwtCompatible;
26 import com.google.common.annotations.GwtIncompatible;
27 import com.google.common.base.Converter;
28
29 import java.io.Serializable;
30 import java.util.AbstractList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.Comparator;
35 import java.util.List;
36 import java.util.RandomAccess;
37
38
39
40
41
42
43
44
45
46
47
48
49 @GwtCompatible(emulated = true)
50 public final class Shorts {
51 private Shorts() {}
52
53
54
55
56
57 public static final int BYTES = Short.SIZE / Byte.SIZE;
58
59
60
61
62
63
64 public static final short MAX_POWER_OF_TWO = 1 << (Short.SIZE - 2);
65
66
67
68
69
70
71
72
73 public static int hashCode(short value) {
74 return value;
75 }
76
77
78
79
80
81
82
83
84
85
86 public static short checkedCast(long value) {
87 short result = (short) value;
88 if (result != value) {
89
90 throw new IllegalArgumentException("Out of range: " + value);
91 }
92 return result;
93 }
94
95
96
97
98
99
100
101
102
103 public static short saturatedCast(long value) {
104 if (value > Short.MAX_VALUE) {
105 return Short.MAX_VALUE;
106 }
107 if (value < Short.MIN_VALUE) {
108 return Short.MIN_VALUE;
109 }
110 return (short) value;
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public static int compare(short a, short b) {
126 return a - b;
127 }
128
129
130
131
132
133
134
135
136
137
138 public static boolean contains(short[] array, short target) {
139 for (short value : array) {
140 if (value == target) {
141 return true;
142 }
143 }
144 return false;
145 }
146
147
148
149
150
151
152
153
154
155
156 public static int indexOf(short[] array, short target) {
157 return indexOf(array, target, 0, array.length);
158 }
159
160
161 private static int indexOf(
162 short[] array, short target, int start, int end) {
163 for (int i = start; i < end; i++) {
164 if (array[i] == target) {
165 return i;
166 }
167 }
168 return -1;
169 }
170
171
172
173
174
175
176
177
178
179
180
181
182 public static int indexOf(short[] array, short[] target) {
183 checkNotNull(array, "array");
184 checkNotNull(target, "target");
185 if (target.length == 0) {
186 return 0;
187 }
188
189 outer:
190 for (int i = 0; i < array.length - target.length + 1; i++) {
191 for (int j = 0; j < target.length; j++) {
192 if (array[i + j] != target[j]) {
193 continue outer;
194 }
195 }
196 return i;
197 }
198 return -1;
199 }
200
201
202
203
204
205
206
207
208
209
210 public static int lastIndexOf(short[] array, short target) {
211 return lastIndexOf(array, target, 0, array.length);
212 }
213
214
215 private static int lastIndexOf(
216 short[] array, short target, int start, int end) {
217 for (int i = end - 1; i >= start; i--) {
218 if (array[i] == target) {
219 return i;
220 }
221 }
222 return -1;
223 }
224
225
226
227
228
229
230
231
232
233 public static short min(short... array) {
234 checkArgument(array.length > 0);
235 short min = array[0];
236 for (int i = 1; i < array.length; i++) {
237 if (array[i] < min) {
238 min = array[i];
239 }
240 }
241 return min;
242 }
243
244
245
246
247
248
249
250
251
252 public static short max(short... array) {
253 checkArgument(array.length > 0);
254 short max = array[0];
255 for (int i = 1; i < array.length; i++) {
256 if (array[i] > max) {
257 max = array[i];
258 }
259 }
260 return max;
261 }
262
263
264
265
266
267
268
269
270
271
272 public static short[] concat(short[]... arrays) {
273 int length = 0;
274 for (short[] array : arrays) {
275 length += array.length;
276 }
277 short[] result = new short[length];
278 int pos = 0;
279 for (short[] array : arrays) {
280 System.arraycopy(array, 0, result, pos, array.length);
281 pos += array.length;
282 }
283 return result;
284 }
285
286
287
288
289
290
291
292
293
294
295
296
297
298 @GwtIncompatible("doesn't work")
299 public static byte[] toByteArray(short value) {
300 return new byte[] {
301 (byte) (value >> 8),
302 (byte) value};
303 }
304
305
306
307
308
309
310
311
312
313
314
315
316
317 @GwtIncompatible("doesn't work")
318 public static short fromByteArray(byte[] bytes) {
319 checkArgument(bytes.length >= BYTES,
320 "array too small: %s < %s", bytes.length, BYTES);
321 return fromBytes(bytes[0], bytes[1]);
322 }
323
324
325
326
327
328
329
330
331 @GwtIncompatible("doesn't work")
332 public static short fromBytes(byte b1, byte b2) {
333 return (short) ((b1 << 8) | (b2 & 0xFF));
334 }
335
336 private static final class ShortConverter
337 extends Converter<String, Short> implements Serializable {
338 static final ShortConverter INSTANCE = new ShortConverter();
339
340 @Override
341 protected Short doForward(String value) {
342 return Short.decode(value);
343 }
344
345 @Override
346 protected String doBackward(Short value) {
347 return value.toString();
348 }
349
350 @Override
351 public String toString() {
352 return "Shorts.stringConverter()";
353 }
354
355 private Object readResolve() {
356 return INSTANCE;
357 }
358 private static final long serialVersionUID = 1;
359 }
360
361
362
363
364
365
366
367 @Beta
368 public static Converter<String, Short> stringConverter() {
369 return ShortConverter.INSTANCE;
370 }
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388 public static short[] ensureCapacity(
389 short[] array, int minLength, int padding) {
390 checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
391 checkArgument(padding >= 0, "Invalid padding: %s", padding);
392 return (array.length < minLength)
393 ? copyOf(array, minLength + padding)
394 : array;
395 }
396
397
398 private static short[] copyOf(short[] original, int length) {
399 short[] copy = new short[length];
400 System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
401 return copy;
402 }
403
404
405
406
407
408
409
410
411
412
413 public static String join(String separator, short... array) {
414 checkNotNull(separator);
415 if (array.length == 0) {
416 return "";
417 }
418
419
420 StringBuilder builder = new StringBuilder(array.length * 6);
421 builder.append(array[0]);
422 for (int i = 1; i < array.length; i++) {
423 builder.append(separator).append(array[i]);
424 }
425 return builder.toString();
426 }
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444 public static Comparator<short[]> lexicographicalComparator() {
445 return LexicographicalComparator.INSTANCE;
446 }
447
448 private enum LexicographicalComparator implements Comparator<short[]> {
449 INSTANCE;
450
451 @Override
452 public int compare(short[] left, short[] right) {
453 int minLength = Math.min(left.length, right.length);
454 for (int i = 0; i < minLength; i++) {
455 int result = Shorts.compare(left[i], right[i]);
456 if (result != 0) {
457 return result;
458 }
459 }
460 return left.length - right.length;
461 }
462 }
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479 public static short[] toArray(Collection<? extends Number> collection) {
480 if (collection instanceof ShortArrayAsList) {
481 return ((ShortArrayAsList) collection).toShortArray();
482 }
483
484 Object[] boxedArray = collection.toArray();
485 int len = boxedArray.length;
486 short[] array = new short[len];
487 for (int i = 0; i < len; i++) {
488
489 array[i] = ((Number) checkNotNull(boxedArray[i])).shortValue();
490 }
491 return array;
492 }
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508 public static List<Short> asList(short... backingArray) {
509 if (backingArray.length == 0) {
510 return Collections.emptyList();
511 }
512 return new ShortArrayAsList(backingArray);
513 }
514
515 @GwtCompatible
516 private static class ShortArrayAsList extends AbstractList<Short>
517 implements RandomAccess, Serializable {
518 final short[] array;
519 final int start;
520 final int end;
521
522 ShortArrayAsList(short[] array) {
523 this(array, 0, array.length);
524 }
525
526 ShortArrayAsList(short[] array, int start, int end) {
527 this.array = array;
528 this.start = start;
529 this.end = end;
530 }
531
532 @Override public int size() {
533 return end - start;
534 }
535
536 @Override public boolean isEmpty() {
537 return false;
538 }
539
540 @Override public Short get(int index) {
541 checkElementIndex(index, size());
542 return array[start + index];
543 }
544
545 @Override public boolean contains(Object target) {
546
547 return (target instanceof Short)
548 && Shorts.indexOf(array, (Short) target, start, end) != -1;
549 }
550
551 @Override public int indexOf(Object target) {
552
553 if (target instanceof Short) {
554 int i = Shorts.indexOf(array, (Short) target, start, end);
555 if (i >= 0) {
556 return i - start;
557 }
558 }
559 return -1;
560 }
561
562 @Override public int lastIndexOf(Object target) {
563
564 if (target instanceof Short) {
565 int i = Shorts.lastIndexOf(array, (Short) target, start, end);
566 if (i >= 0) {
567 return i - start;
568 }
569 }
570 return -1;
571 }
572
573 @Override public Short set(int index, Short element) {
574 checkElementIndex(index, size());
575 short oldValue = array[start + index];
576
577 array[start + index] = checkNotNull(element);
578 return oldValue;
579 }
580
581 @Override public List<Short> subList(int fromIndex, int toIndex) {
582 int size = size();
583 checkPositionIndexes(fromIndex, toIndex, size);
584 if (fromIndex == toIndex) {
585 return Collections.emptyList();
586 }
587 return new ShortArrayAsList(array, start + fromIndex, start + toIndex);
588 }
589
590 @Override public boolean equals(Object object) {
591 if (object == this) {
592 return true;
593 }
594 if (object instanceof ShortArrayAsList) {
595 ShortArrayAsList that = (ShortArrayAsList) object;
596 int size = size();
597 if (that.size() != size) {
598 return false;
599 }
600 for (int i = 0; i < size; i++) {
601 if (array[start + i] != that.array[that.start + i]) {
602 return false;
603 }
604 }
605 return true;
606 }
607 return super.equals(object);
608 }
609
610 @Override public int hashCode() {
611 int result = 1;
612 for (int i = start; i < end; i++) {
613 result = 31 * result + Shorts.hashCode(array[i]);
614 }
615 return result;
616 }
617
618 @Override public String toString() {
619 StringBuilder builder = new StringBuilder(size() * 6);
620 builder.append('[').append(array[start]);
621 for (int i = start + 1; i < end; i++) {
622 builder.append(", ").append(array[i]);
623 }
624 return builder.append(']').toString();
625 }
626
627 short[] toShortArray() {
628
629 int size = size();
630 short[] result = new short[size];
631 System.arraycopy(array, start, result, 0, size);
632 return result;
633 }
634
635 private static final long serialVersionUID = 0;
636 }
637 }